# Table of Contents

# 의존성 추가

Spring Data MongoDB를 사용하려면 다음 의존성을 추가해야한다.

// build.gradle
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
}

# 환경 설정

application.properties 파일에 설정 값을 추가한다.

spring.data.mongodb.host=localhost 
spring.data.mongodb.port=27017
spring.data.mongodb.username=
spring.date.mongodb.password=

# Document 정의

# @Document

객체에 @Document를 추가하여 클래스를 도큐먼트에 매핑할 수 있다.

@Document
public class MemberDocument {
    // ... 
}

@Documentcollection 속성으로 콜렉션 이름을 지정할 수 있다.

@Document(collection = "member")
public class MemberDocument {
    // ... 
}

# @id

@id 어노테이션으로 _id 필드를 지정하지 않으면 데이터를 삽입할 때 자동으로 ObjectId가 할당된다.





 
 



















@Document(collection = "member")
@Getter
public class MemberEntity {

    // @Id
    // private Long id;

    @Field
    private String email;

    @Field
    private String name;

    @Field
    private Boolean isMarried;

    @Field
    private Integer age;

    @Field
    private Double weight;

    // ..
}

이 경우 _id 필드에 ObjectId 타입의 데이터가 자동으로 생성된다.



 








> db.member.find().pretty()
{
	"_id" : ObjectId("625beebf086eef0b837f3a57"),
	"email" : "Paul@gmai.com",
	"name" : "Paul",
	"isMarried" : true,
	"age" : 25,
	"weight" : 170.3,
	"_class" : "com.yologger.spring_mongodb.data.MemberEntity"
}

물론 명시적으로 _id 필드를 지정할 수 있다. 이 경우도 _id 필드에 ObjectId 타입의 데이터가 자동으로 생성된다.





 
 
 



















@Document(collection = "member")
@Getter
public class MemberEntity {

    @Id
    @Field("_id", targetType = FieldType.OBJECT_ID)
    private ObjectId id;

    @Field
    private String email;

    @Field
    private String name;

    @Field
    private Boolean isMarried;

    @Field
    private Integer age;

    @Field
    private Double weight;

    // ...                                 
}

다른 데이터 타입을 id 필드로 사용할 수 있다. 이 경우 _id필드가 자동으로 생성되지 않으므로 직접 구현해야한다.





 
 




@Document(collection = "member")
@Getter
public class MemberEntity {

    @Id
    private String id;

    // ...                                 
}

# @Field

@Field를 사용하여 필드를 지정할 수 있다.





 


 


 


 


 





@Document(collection = "member")
@Getter
public class MemberDocument {

    @Field
    private String email;

    @Field
    private String name;

    @Field
    private Boolean isMarried;

    @Field
    private Integer age;

    @Field
    private Double weight;

    // ...
}

필드 이름을 직접 지정할 수 있다.

@Document(collection = "member")
@Getter
public class MemberDocument {

    @Field("is_married")
    private Boolean isMarried;

    // ...
}

# @CreatedDate, @LastModifiedDate

@CreatedDate를 추가하면 도큐먼트가 생성된 날짜와 시간을 추가할 수 있다. @LastModifiedDate를 추가하면 마지막으로 도큐먼트가 변경된 날짜와 시간을 추가할 수 있다.

이를 위해 먼저 구성 클래스에 @EnableMongoAuditing 어노테이션을 추가해야한다.


 



@Configuration
@EnableMongoAuditing
public class MongoConfig {
}

그 다음 도큐먼트 클래스를 다음과 같이 정의하면 된다.























 
 
 

 
 
 











@Document(collection = "member")
@Getter
public class MemberDocument {

    @Id
    private ObjectId id;

    @Field
    private String email;

    @Field
    private String name;

    @Field(name="is_married")
    private Boolean isMarried;

    @Field
    private Integer age;

    @Field
    private Double weight;

    @CreatedDate
    @Field
    private LocalDateTime createdAt;

    @LastModifiedDate
    @Field
    private LocalDateTime updatedAt;

    @Builder
    public MemberDocument(String email, String name, Boolean isMarried, Integer age, Double weight) {
        this.email = email;
        this.name = name;
        this.isMarried = isMarried;
        this.age = age;
        this.weight = weight;
    }
}

보통 베이스 클래스를 정의하고 이를 상속하는 형태로 구현한다.



 
 
 

 
 
 


public class BaseDocument {

    @CreatedDate
    @Field
    private LocalDateTime createdAt;

    @LastModifiedDate
    @Field
    private LocalDateTime updatedAt;
}


 




@Document(collection = "member")
@Getter
public class MemberDocument extends BaseDocument {

    // ...
}

# CRUD 작업 실행하기

Spring Data MongoDBMongoDB에 접근하기 위한 두 가지 방법을 제공한다.

  • MongoTemplate
  • MongoRepository

# MongoTemplate

MongoTemplate는 Mongo DB CRUD 작업을 위한 메소드를 제공하는 클래스다.







 



























import org.springframework.data.mongodb.core.MongoTemplate;

@DataMongoTest
class MemberRepositoryTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    public void test() {

        MemberDocument member1 = MemberDocument.builder()
            .email("Son@gmai.com")
            .name("Son")
            .age(25)
            .isMarried(true)
            .weight(170.3)
            .build();

        MemberDocument member2 = MemberDocument.builder()
            .email("Kane@gmai.com")
            .name("Kane")
            .age(33)
            .isMarried(false)
            .weight(150.8)
            .build();

        mongoTemplate.insert(member1, "member");
        mongoTemplate.insert(member2, "member");

        assertThat(mongoTemplate.findAll(MemberDocument.class, "member").size()).isEqualTo(2);
    }
}

데이터베이스에 저장된 Document는 다음과 같다.

> db.member.find().pretty()
{
	"_id" : ObjectId("62786ada2e2278137ac8b3bd"),
	"email" : "Paul@gmai.com",
	"name" : "Paul",
	"is_married" : true,
	"age" : 25,
	"weight" : 170.3,
	"createdAt" : ISODate("2022-05-09T01:14:02.368Z"),
	"updatedAt" : ISODate("2022-05-09T01:14:02.368Z"),
	"_class" : "com.yologger.spring_mongodb.data.MemberDocument"
}
{
	"_id" : ObjectId("62786ada2e2278137ac8b3be"),
	"email" : "Monica@gmai.com",
	"name" : "Monica",
	"is_married" : false,
	"age" : 33,
	"weight" : 150.8,
	"createdAt" : ISODate("2022-05-09T01:14:02.487Z"),
	"updatedAt" : ISODate("2022-05-09T01:14:02.487Z"),
	"_class" : "com.yologger.spring_mongodb.data.MemberDocument"
} 

MongoTemplate는 정말 많은 메소드를 제공한다. 공식 문서 (opens new window)에서 다양한 기능을 확인할 수 있다.

# MongoRepository

MongoRepository은 더욱 추상화된 방법을 제공한다.

public interface MemberRepository extends MongoRepository<MemberDocument, ObjectId> {
}

MongoRepository는 다음과 같은 상속 관계를 갖는다.

따라서 CrudRepository, PagingAndSortingRepository가 제공하는 메소드를 모두 사용할 수 있다.

@DataMongoTest
class MemberRepositoryTest {

    @Autowired
    private MemberRepository memberRepository;

    @Test
    void test() {
        MemberDocument member1 = MemberDocument.builder()
                .email("Paul@gmai.com")
                .name("Paul")
                .age(25)
                .isMarried(true)
                .weight(170.3)
                .build();

        MemberDocument member2 = MemberDocument.builder()
                .email("Monica@gmai.com")
                .name("Monica")
                .age(33)
                .isMarried(false)
                .weight(150.8)
                .build();

        memberRepository.save(member1);
        memberRepository.save(member2);

        List<MemberDocument> members = memberRepository.findAll();

        assertThat(members.size()).isEqualTo(2);
    }
}

# 단위 테스트

Spring Data MongoDB는 @DataMongoTest 어노테이션을 제공한다. 이 어노테이션을 추가하면 Mongo DB와 관련된 컴포넌트만 Spring IoC Container에 등록한다.

import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;

@DataMongoTest
class MemberRepositoryTest {

    @Autowired
    private MemberRepository memberRepository;

    @Test
    void test() {
        MemberDocument member1 = MemberDocument.builder()
                .email("Paul@gmai.com")
                .name("Paul")
                .age(25)
                .isMarried(true)
                .weight(170.3)
                .build();

        MemberDocument member2 = MemberDocument.builder()
                .email("Monica@gmai.com")
                .name("Monica")
                .age(33)
                .isMarried(false)
                .weight(150.8)
                .build();

        memberRepository.save(member1);
        memberRepository.save(member2);

        assertThat(memberRepository.count()).isEqualTo(2);
    }
}